/// @tags: Burnside Pólya
#include <cstdio>
#include <cstring>
#include <iostream>
#define rint register int

using std::cin;
using std::cout;

namespace BlueQuantum {

constexpr int maxs = 23, maxn = maxs * 3;

int mod;
bool vis[maxn];
int trans[maxn], siz[maxn], f[maxs][maxs][maxs];

inline int calc(int r, int b, int g) {
  int ccnt = 0;
  int n = r + b + g;
  memset(f, 0, sizeof(f));
  memset(vis, 0, sizeof(vis));
  for (int i = 1, p, len; i <= n; ++i)
    if (!vis[i]) {
      p = i;
      len = 0;
      while (!vis[p]) {
        ++len;
        vis[p] = true;
        p = trans[p];
      }
      siz[++ccnt] = len;
    }
  f[0][0][0] = 1;
  for (int i = 1; i <= ccnt; ++i)
    for (int j = r; j >= 0; --j)
      for (int k = b; k >= 0; --k)
        for (int l = g; l >= 0; --l) {
          if (j >= siz[i]) f[j][k][l] = (f[j][k][l] + f[j - siz[i]][k][l]) % mod;
          if (k >= siz[i]) f[j][k][l] = (f[j][k][l] + f[j][k - siz[i]][l]) % mod;
          if (l >= siz[i]) f[j][k][l] = (f[j][k][l] + f[j][k][l - siz[i]]) % mod;
        }
  return f[r][b][g];
}

inline int qpow(int base, int exp) {
  int res = 1;
  for (; exp; exp >>= 1, base = base * base % mod)
    if (exp & 1) res = res * base % mod;
  return res;
}

inline int main() {
  int r, g, b, m;
  cin >> r >> b >> g;
  int n = r + b + g;
  cin >> m >> mod;
  int ans = 0;
  for (int i = 1; i <= m; ++i) {
    for (int j = 1; j <= n; ++j) cin >> trans[j];
    (ans += calc(r, b, g)) %= mod;
  }
  for (int j = 1; j <= n; ++j) trans[j] = j;
  (ans += calc(r, b, g)) %= mod;
  cout << ans * qpow(m + 1, mod - 2) % mod;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P1446 [HNOI2008] Cards.in", "r", stdin);
  freopen("P1446 [HNOI2008] Cards.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
